﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using 枸杞VBE插件.代码库;

//using static 枸杞VBE插件.代码库.代码库助手;
using 代码模块 = NetOffice.VBIDEApi.CodeModule;
using static 枸杞VBE插件.VBE助手;
using NetOffice.VBIDEApi;
using MiniExcelLibs;

namespace 枸杞VBE插件.窗体
{
    public partial class 代码库窗体 : Form//, Rougamo.IRougamo<DebugAttribute>
    {
        private readonly ContextMenuStrip 右键菜单 = new ContextMenuStrip();
        private readonly Dictionary<String, TreeNode> 节点字典 = new Dictionary<String, TreeNode>();
        private bool 代码库动了没 = false;

        public 代码库窗体()
        {
            InitializeComponent();
        }

        private void 按钮保存修改_Click(object sender, EventArgs e)
        {
            var 代码 = new 代码库助手.代码()
            {
                关键字 = TV.SelectedNode.Name,
                代码类型 = this.代码类型.Text,
                代码文本 = 代码区.Text,
            };
            代码库助手.更新代码(代码);
            代码库动了没 = true;
            TV.SelectedNode.Tag = 代码区.Text;
        }

        [Info]
        private void 代码库窗体_Load(object sender, EventArgs e)
        {
            右键菜单.Items.Add("修改名称").Click += (o, ev) => TV.SelectedNode.BeginEdit();
            右键菜单.Items.Add("新建同级").Click += 新建同级;
            右键菜单.Items.Add("新建下级").Click += (o, ev) => TV.SelectedNode.Nodes.Add("重命名").BeginEdit();
            右键菜单.Items.Add("收藏语句").Click += 收藏语句;
            右键菜单.Items.Add("收藏函数").Click += 收藏函数;
            右键菜单.Items.Add("收藏模块").Click += 收藏模块;
            右键菜单.Items.Add("删除选中").Click += 删除选中节点;
            右键菜单.Items.Add("全部展开").Click += (o, ev) => TV.SelectedNode.ExpandAll();
            右键菜单.Items.Add("全部折叠").Click += (o, ev) => TV.SelectedNode.Collapse(true);
        }

        [Info]
        private void 删除选中节点(object sender, EventArgs e)
        {
            var find = 代码库助手.CodeDb
                .Find(x => x.关键字.Contains($@"枸杞VBE工具栏\{TV.SelectedNode.FullPath}"))
                .First();
            find.是否启用 = false;
            代码库助手.CodeDb.Update(find);

            // .Where(x=>x.关键字.Contains($@"枸杞VBE工具栏\{TV.SelectedNode.FullPath}"))
            //  .

            //var sql = $@"delete from 代码库  where 关键字 like '{@"枸杞VBE工具栏\" + TV.SelectedNode.FullPath}%'";
            //代码库.执行SQL命令(sql);
            //代码库助手.CodeDb.Update.Updateable<代码库助手.代码>()
            //    .SetColumns(x => x.是否启用 == false)
            //    .Where(x => SqlSugar.SqlFunc.Contains(x.关键字, $@"枸杞VBE工具栏\{TV.SelectedNode.FullPath}%"))
            //    .ExecuteCommand();

            //代码库助手.代码库.Deleteable<代码库助手.代码>(x => SqlSugar.SqlFunc.Contains(x.关键字, $@"枸杞VBE工具栏\{TV.SelectedNode.FullPath}%")).ExecuteCommand();
            代码库动了没 = true;
            TV.SelectedNode.Remove();
        }

        [Info]
        private void 收藏模块(object sender, EventArgs e)
        {
            代码模块 活动代码模块 = VBE助手实例.VBE对象.ActiveCodePane.CodeModule;
            string 代码文本 = 活动代码模块.Lines(1, 活动代码模块.CountOfLines);
            //    Dim 节点 As TreeNode
            //If TV.SelectedNode.Parent Is Nothing Then
            //    节点 = TV.Nodes.Add(活动代码模块.Name)
            //Else
            //    节点 = TV.SelectedNode.Parent.Nodes.Add(活动代码模块.Name)
            //End If
            //TreeNode 节点 = TV.SelectedNode.Parent == null ? TV.Nodes.Add(活动代码模块.Name) : TV.SelectedNode.Parent.Nodes.Add(活动代码模块.Name);
            var 节点 = (TV.SelectedNode.Parent?.Nodes ?? TV.Nodes).Add(活动代码模块.Name);
            节点.Name = @"枸杞VBE工具栏\" + 节点.FullPath;
            节点.Tag = 代码文本;
            节点.ToolTipText = "模块";
            节点字典[节点.Name] = 节点;
        }

        [Info]
        private void 收藏函数(object sender, EventArgs e)
        {
            VBE助手实例.VBE对象.ActiveCodePane.GetSelection(out int 起始行号, out _, out _, out _);
            代码模块 活动代码模块 = VBE助手实例.VBE对象.ActiveCodePane.CodeModule;
            string 当前过程名 = 活动代码模块.ProcOfLine(起始行号, out NetOffice.VBIDEApi.Enums.vbext_ProcKind 类型);
            起始行号 = 活动代码模块.ProcStartLine(当前过程名, 类型);
            int 总行数 = 活动代码模块.ProcCountLines(当前过程名, 类型);
            string 代码文本 = 活动代码模块.Lines(起始行号, 总行数);
            //TreeNode 节点 = TV.SelectedNode.Parent == null ? TV.Nodes.Add(当前过程名) : TV.SelectedNode.Parent.Nodes.Add(当前过程名);
            var 节点 = (TV.SelectedNode.Parent?.Nodes ?? TV.Nodes).Add(当前过程名);
            //if (TV.SelectedNode.Parent == null)
            //{
            //    节点 = TV.Nodes.Add(当前过程名);
            //}
            //else
            //{
            //    节点 = TV.SelectedNode.Parent.Nodes.Add(当前过程名);
            //}
            节点.Name = @"枸杞VBE工具栏\" + 节点.FullPath;
            节点.Tag = 代码文本;
            节点.ToolTipText = "函数";
            节点字典[节点.Name] = 节点;
        }

        [Info]
        private void 收藏语句(object sender, EventArgs e)
        {
            TreeNode 节点;
            VBE助手实例.VBE对象.ActiveCodePane.GetSelection(out int 起始行号, out _, out int 结束行号, out _);
            string 代码文本 = VBE助手实例.VBE对象.SelectedVBComponent.CodeModule.Lines(起始行号, 结束行号 - 起始行号 + 1);
            if (TV.SelectedNode.Parent == null)
            {
                节点 = TV.Nodes.Add("");
            }
            else
            {
                节点 = TV.SelectedNode.Parent.Nodes.Add("");
            }
            节点.Name = @"枸杞VBE工具栏\" + 节点.FullPath;
            节点.Tag = 代码文本;
            节点.ToolTipText = "语句";
            节点字典[节点.Name] = 节点;
            节点.BeginEdit();
        }

        [Info]
        private void 新建同级(object sender, EventArgs e)
        {
            if (TV.SelectedNode.Parent == null)
            {
                TV.Nodes.Add("重命名").BeginEdit();
            }
            else
            {
                TV.SelectedNode.Parent.Nodes.Add("重命名").BeginEdit();
            }
        }

        public void 生成TV树()
        {
            TV.Nodes.Clear();
            节点字典.Clear();
            //var dt = 代码库.获取记录集("select * from 代码库");
            //var x =
            //    from r in dt.AsEnumerable()
            //    orderby r[0].ToString()
            //    select r;
            //foreach (DataRow r in x)
            //{
            //    string 关键字 = r["关键字"].ToString();
            //    TreeNode 节点 = 生成节点(关键字);
            //    节点.ToolTipText = r["代码类型"].ToString();
            //    节点.Tag = r["代码文本"].ToString();
            //    节点字典[关键字] = 节点;
            //}
            代码库助手.查询所有已启用代码()
                .ForEach(a =>
                {
                    TreeNode 节点 = 生成节点(a.关键字);
                    节点.ToolTipText = a.代码类型;
                    节点.Tag = a.代码文本;
                    节点字典[a.关键字] = 节点;
                });
            if (TV.Nodes.Count > 0)
            {
                TV.SelectedNode = TV.Nodes[1];
                TV.CollapseAll();
            }
            //TV.ExpandAll()
        }

        private TreeNode 生成节点(string 关键字)
        {
            if (节点字典.ContainsKey(关键字))
            {
                return 节点字典[关键字];
            }
            else
            {
                string 上级 = 命令.上级(关键字);
                string 本级 = 命令.本级(关键字);
                // Mid(关键字, InStrRev(关键字, "\") + 1)
                if (上级 == "枸杞VBE工具栏" || 上级 == "")
                {
                    return TV.Nodes.Add(关键字, 本级);
                }
                else
                {
                    return 生成节点(上级).Nodes.Add(关键字, 本级);
                }
            }
        }

        private void 展开父级(TreeNode 节点)
        {
            if (节点.Parent == null) return;
            节点.Parent.Expand();
            展开父级(节点.Parent);
        }

        [Info]
        private void 代码库窗体_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Hide();
            e.Cancel = true;
            if (代码库动了没)
            {
                VBE助手实例.生成主菜单栏();
                代码库动了没 = false;
            }
        }

        private void TV_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            展开父级(e.Node);
        }

        [Info]
        private void 导入Excel_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog()
            {
                Title = "选择要导入的Excel文件",
                Filter = "Excel files|*.xlsx|All files|*.*"
            };
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            var l = MiniExcel.Query<代码库助手.代码>(openFileDialog.FileName).ToList();
            代码库助手.更新代码(l);
            代码库动了没 = true;
            生成TV树();
        }

        [Info]
        private void 导出Excel_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog()
            {
                Title = "保存到Excel文件",
                Filter = "Excel files|*.xlsx|All files|*.*",
                FileName = "代码库导出" + DateTime.Now.ToString("dd-MM-yyyy") + ".xlsx"
            };
            if (saveFileDialog1.ShowDialog() != DialogResult.OK) return;
            var l = 代码库助手.查询代码库();
            MiniExcel.SaveAs(saveFileDialog1.FileName, l);
        }

        [Debug]
        private void TV_AfterSelect(object sender, TreeViewEventArgs e)
        {
            代码区.Text = e.Node.Tag?.ToString().Replace("\n", "\r\n") ?? "";
            代码类型.Text = e.Node.ToolTipText;
            if (!e.Node.IsExpanded)
            {
                e.Node.Expand();
            }
            else
            {
                e.Node.Collapse(false);
            }
        }

        private void TV_AfterExpand(object sender, TreeViewEventArgs e)
        {
            foreach (TreeNode n in e.Node.Parent?.Nodes ?? TV.Nodes) if (n != e.Node) n.Collapse();
        }

        private void TV_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Right) 右键菜单.Show(Cursor.Position);
        }

        private readonly List<string> 查找结果 = new List<string>();

        private void 查找文本框_TextChanged(object sender, EventArgs e)
        {
            if (查找文本框.Text == "")
            {
                listBox1.Visible = false;
            }
            else
            {
                listBox1.Visible = true;
                listBox1.Items.Clear();
                查找结果.Clear();
                foreach (TreeNode t in TV.Nodes)
                {
                    递归判断节点(t);
                }
            }
        }

        private void 递归判断节点(TreeNode t)
        {
            if (t.Nodes.Count == 0)
            {
                if (t.Tag.ToString().IndexOf(查找文本框.Text, StringComparison.OrdinalIgnoreCase) > 0
                    || t.Text.IndexOf(查找文本框.Text, StringComparison.OrdinalIgnoreCase) > 0)
                {
                    listBox1.Items.Add(t.Text);
                    查找结果.Add(t.Tag.ToString());
                }
            }
            else
            {
                foreach (TreeNode tt in t.Nodes)
                {
                    递归判断节点(tt);
                }
            }
        }

        private void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var n = listBox1.SelectedIndex;
            this.代码区.Text = 查找结果[n]?.ToString().Replace("\n", "\r\n") ?? "";
        }

        private void 返回按钮_Click(object sender, EventArgs e)
        {
            查找文本框.Text = "";
            listBox1.Visible = false;
        }
    }
}